package cn.zhc.com.http;


import android.content.Context;
import android.text.TextUtils;

import org.json.JSONObject;

import cn.zhc.com.http.cache.DiskLruCache;
import cn.zhc.com.http.cache.UtilsHttpCache;
import cn.zhc.com.http.code.HttpCode;
import cn.zhc.com.http.https.HttpsSupport;
import cn.zhc.com.http.interceptors.LoggerInterceptor;
import cn.zhc.com.http.listener.OnHttpRequestListener;
import cn.zhc.com.http.listener.OnHttpUploadListener;
import cn.zhc.com.http.upload.UploadFileRequestBody;
import cn.zhc.com.utils.UtilsOther;
import cn.zhc.com.utils.UtilsGson;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;

import cn.zhc.com.utils.UtilsLog;
import cn.zhc.com.utils.UtilsShA1;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by zhouhongchun on 2017/8/8.
 */

public class UtilsHttp {
    private static RetrofitApi mManagerApi;

    /**
     * 初始化网络框架
     */
    public static synchronized RetrofitApi initOkHttp(){
        if (mManagerApi == null){
            mManagerApi = initApiManager(initRetrofit(initHttpClient()));
        }
        return mManagerApi;
    }
    private static OkHttpClient initHttpClient(){
//        持久化保存cookie
//        ClearableCookieJar mSharedPrefsCookie = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(getApplicationContext()));
//        运行时保存cookie
//        CookieJarImpl mMemoryCookie = new CookieJarImpl(new MemoryCookieStore());
        HttpsSupport.SSLParams sslParams = null;
        sslParams = HttpsSupport.getSslSocketFactory(null, null, null);
//        try {
//            // 添加证书
//            InputStream[] certificates = new InputStream[1];
//            certificates[0] = getAssets().open("chetuanapp10.crt");
//            sslParams = HttpsSupport.getSslSocketFactory(certificates, null, null);
//        } catch (Exception e) {
//            e.printStackTrace();
//            sslParams = HttpsSupport.getSslSocketFactory(null, null, null);
//        }

        Interceptor mInterceptor = new LoggerInterceptor(LoggerInterceptor.TAG_DEFAULT, UtilsLog.LogEnable,UtilsLog.LogEnable);
        return new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)//设置失败重连
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .addInterceptor(mInterceptor)
                //20MB
//                .cache(new okhttp3.Cache(file, 1024*1024*20))
//                .cookieJar(mMemoryCookie)
                .hostnameVerifier(new HostnameVerifier()
                {
                    @Override
                    public boolean verify(String hostname, SSLSession session)
                    {
                        return true;
                    }
                })
                .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
                .build();
    }
    private static  Retrofit initRetrofit(OkHttpClient mOkHttpClient){
        return new Retrofit.Builder()
                .client(mOkHttpClient)
                .baseUrl(HttpManager.BaseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

    }
    private static  RetrofitApi initApiManager(Retrofit mRetrofit){
        return mRetrofit.create(RetrofitApi.class);
    }

    public static String dealHttpCache(Context context,boolean needCache,String IDUrl,String params,OnHttpRequestListener mOnHttpRequestListener){
        String cacheTag = null;
        if (needCache){
            cacheTag = UtilsShA1.encryp(IDUrl + params);
            UtilsHttp.loadOkHttpCache(context,cacheTag,IDUrl,mOnHttpRequestListener);
        }
        return cacheTag;
    }
    /**
     * 如果后台给的数据比较渣渣，建议用这个来处理返回数据
     * @param responseJson
     * @return
     */
    public static boolean dealHttpResponse(String responseJson) {
        try {
            String temp = (String) new JSONObject(responseJson).get("errcode");
            if (HttpCode.HTTP_CODE_SUCCESS.equals(temp)){
                return true;
            }
        }catch (Exception e){

        }
        return false;
    }


    /**
     * 上传图片类型的文件
     * @return
     */
    public static MediaType getImageMediaType(String prefix){
        MediaType mMediaType = null;
        if (TextUtils.equals(prefix, "jpg")) {
            mMediaType = MediaType.parse("image/jpg");
        } else if (TextUtils.equals(prefix, "mp4")) {
            mMediaType = MediaType.parse("video/mpeg");
        }
        return MediaType.parse("image/jpg");
    }

    /**
     * 文件上传：构建List<MultipartBody.Part>，并设置监听
     */
    public static List<MultipartBody.Part> filesToMultipartBodyParts(List<File> files, OnHttpUploadListener mProgressListener, int IDUrl) {
        List<MultipartBody.Part> parts = null;
        try {
            parts = new ArrayList<MultipartBody.Part>(files.size());
            for (int i = 0; i < files.size(); i++) {
                //判断文件后缀名
                String fileName = files.get(i).getName();
                String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);
                RequestBody requestBody = RequestBody.create(getImageMediaType(prefix), files.get(i));
                requestBody = new UploadFileRequestBody(requestBody, mProgressListener, i, IDUrl);
                MultipartBody.Part part = MultipartBody.Part.createFormData(prefix, fileName, requestBody);
                parts.add(part);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }


        return parts;
    }

    /**
     * 加载网络数据的缓存
     *
     * @param tag                    url+params的md5值，作为网络缓存的标识
     * @param IDUrl                  作为网络请求的标识
     * @param mOnHttpRequestListener 回调
     */
    public static void loadOkHttpCache(Context context,String tag, String IDUrl, OnHttpRequestListener mOnHttpRequestListener) {
        try {
            DiskLruCache.Snapshot snapShot = UtilsHttpCache.initDiskLruCache(context).get(tag);
            if (snapShot != null && UtilsOther.checkActivityRunning(context)) {
                //TODO 根据自己的项目需求设置缓存内容
//                NetworkBean cache = new Gson().fromJson(snapShot.getString(0), NetworkBean.class);
//                mOnHttpRequestListener.onStart(IDUrl, true);
//                mOnHttpRequestListener.onNext(cache, IDUrl, true);
//                mOnHttpRequestListener.onCompleted(IDUrl, true);


            } else {
                new Exception("DiskLruCache.Snapshot is null");
//                mOnHttpRequestListener.onError(new Exception("DiskLruCache.Snapshot is null"),IDUrl,true);
            }
        } catch (Exception e) {
            e.printStackTrace();
//            mOnHttpRequestListener.onError(e,IDUrl,true);

        }
    }

    /**
     * 添加线程管理并订阅
     */
    public static void toSubscribe(final Context context, Observable mObservable, final String IDUrl, final OnHttpRequestListener mOnHttpRequestListener, final boolean needCache, final String cacheTag) {
        mObservable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Object>() {
                    @Override
                    public void onStart() {
                        super.onStart();
                        mOnHttpRequestListener.onStart(IDUrl, false);
                    }

                    @Override
                    public void onNext(Object data) {
                        final String temp = UtilsGson.toJson(data);
                        if (needCache) {
                            new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    try {
                                        DiskLruCache.Editor mEditor = UtilsHttpCache.initDiskLruCache(context).edit(cacheTag);
                                        mEditor.set(0, UtilsGson.toJson(temp));
                                        mEditor.commit();
                                        //这种写法有bug
//                                    DemoApplication.mDiskLruCache.edit(tag).newOutputStream(0).write(response.getBytes());
                                    } catch (Exception e) {

                                    }

                                }
                            }).start();
                        }
                        if (UtilsOther.checkActivityRunning(context)){

                            mOnHttpRequestListener.onNext(temp, IDUrl, false);
                        }else{
                            this.unsubscribe();
                        }

                    }

                    @Override
                    public void onCompleted() {
                        if (!UtilsOther.checkActivityRunning(context)){
                            this.unsubscribe();
                            mOnHttpRequestListener.onCompleted(IDUrl, false);
                        }else{
                            this.unsubscribe();
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        if (UtilsOther.checkActivityRunning(context)){
                            mOnHttpRequestListener.onError(e, IDUrl, false);
                        }else{
                            this.unsubscribe();
                        }

                    }
                });
    }
}
